package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
	"text/tabwriter"

	"github.com/bobappleyard/readline"
	"github.com/mgutz/ansi"
)

const (
	API     = "YouDaoCV"
	API_KEY = "659600698"
)

func init() {
	log.SetFlags(log.Lshortfile)
}

func main() {
	// full := flag.Bool("f", false, "print full web reference, only the first 3,results will be printed without this flag.")
	// simple := flag.Bool("s", false, "only show explainations. argument \"-f\" will not take effect")
	// selection := flag.Bool("x", false, "show explaination of current selection")
	// color := flag.String("color", "auto", "colorize the output. Default to 'auto' or can be 'never' or 'always'.")
	// flag.StringVar(&words, "words", "", "words to lookup, or quoted sentences to translate.")
	flag.Parse()
	words := flag.Args()
	// _ = full
	// _ = simple
	// _ = selection
	// _ = color
	// log.Println("words", words)

	fileName := "ydcv.log"
	logFile, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	defer logFile.Close()
	fileLog := log.New(logFile, "", log.Lshortfile)
	if err != nil {
		log.Fatalln("open file error !")
	}
	fileLog.Println("start run")
	if len(words) > 0 {
		for _, word := range words {
			// log.Println("word:", words[word])
			lookupWord(word)
			fileLog.Println(word)
		}
	} else {
		for {
			word, err := readline.String("> ")
			if err == io.EOF {
				break
			}
			if err != nil {
				fmt.Println("error: ", err)
				break
			}
			lookupWord(word)
			fileLog.Println(word)
			readline.AddHistory(word)
		}
	}
}

func lookupWord(word string) {
	word = url.QueryEscape(word)
	url := fmt.Sprintf("http://fanyi.youdao.com/openapi.do?keyfrom=%s&key=%s&type=data&doctype=json&version=1.1&q=%s", API, API_KEY, word)
	// log.Println("url", url)
	data, err := httpget(url)
	// log.Println(data, err)
	if err != nil {
		log.Fatalln(err)
	}
	printExplanation(data)
}

func printExplanation(data string) {
	type Data struct {
		Basic struct {
			Explains    []string `json:"explains"`
			Phonetic    string   `json:"phonetic"`
			Uk_Phonetic string   `json:"uk-phonetic"`
			Us_Phonetic string   `json:"us-phonetic"`
		} `json:"basic"`
		ErrorCode   float64  `json:"errorCode"`
		Query       string   `json:"query"`
		Translation []string `json:"translation"`
		Web         []struct {
			Key   string   `json:"key"`
			Value []string `json:"value"`
		} `json:"web"`
	}
	var j Data
	json.Unmarshal([]byte(data), &j)
	// log.Println(j)
	// pp.Println(j)
	query := ansi.Color(j.Query, "red+u")
	fmt.Printf("%s [%s]\n", query, j.Basic.Phonetic)
	for _, v := range j.Basic.Explains {
		fmt.Println("* ", ansi.Color(v, "yellow"))
	}
	// fmt.Println("-----------")
	w := new(tabwriter.Writer)
	w.Init(os.Stdout, 2, 8, 0, '\t', 0)
	// w.Init(output, minwidth, tabwidth, padding, padchar, flags)
	for _, v := range j.Web {
		fmt.Fprintf(w, "%s\t:%s\n", v.Key, strings.Join(v.Value, ", "))

	}
	w.Flush()
}

func httpget(url string) (string, error) {
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return string(body), err
}
